import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit'
import { message } from 'antd'
import { MenuItem, BreadcrumbItem } from '@/types/menu'
import menuService, { MenuFormData } from '@/services/menu'

/**
 * 标签页项类型定义
 */
export interface TabItem {
  /** 标签页唯一标识 */
  key: string
  /** 标签页显示标题 */
  title: string
  /** 标签页对应的路径 */
  path: string
  /** 是否可关闭，默认为true */
  closable?: boolean
  /** 是否固定标签页，固定的标签页不能关闭 */
  affix?: boolean
  /** 对应的组件名称，用于直接渲染组件 */
  component?: string
}

/**
 * 菜单状态接口定义
 */
interface MenuState {
  // 菜单相关状态
  /** 菜单列表数据 */
  menuList: MenuItem[]
  /** 当前选中的菜单项key数组 */
  selectedKeys: string[]
  /** 当前展开的菜单项key数组 */
  openKeys: string[]
  /** 菜单是否折叠 */
  collapsed: boolean
  /** 菜单数据加载状态 */
  loading: boolean
  /** 错误信息 */
  error: string | null
  
  // 面包屑相关状态
  /** 面包屑导航列表 */
  breadcrumbList: BreadcrumbItem[]
  
  // 搜索相关状态
  /** 搜索关键词 */
  searchValue: string
  /** 搜索框是否可见 */
  searchVisible: boolean
  
  // 标签页相关状态 - 使用结构化格式存储
  /** 已打开的标签页列表 - 结构化存储 */
  tagList: {
    dataType: 'array'
    content: TabItem[]
    datetime: number
  }
  /** 当前激活的标签页 - 结构化存储 */
  tag: {
    dataType: 'string'
    content: string
    datetime: number
  }
}

// ============ 异步thunk actions ============

/**
 * 获取菜单列表的异步thunk
 * 用于管理员界面的菜单管理功能
 */
export const fetchMenuList = createAsyncThunk(
  'menu/fetchMenuList',
  async (_, { rejectWithValue }) => {
    try {
      const response = await menuService.getMenuList()
      if (response.code === 200) {
        return response.data
      } else {
        return rejectWithValue(response.message || '获取菜单列表失败')
      }
    } catch (error: any) {
      return rejectWithValue(error.message || '获取菜单列表失败')
    }
  }
)

/**
 * 创建菜单的异步thunk
 * 用于新增菜单项的功能
 */
export const createMenu = createAsyncThunk(
  'menu/createMenu',
  async (menuData: MenuFormData, { rejectWithValue }) => {
    try {
      const response = await menuService.createMenu(menuData)
      if (response.code === 200) {
        message.success('菜单创建成功')
        return response.data
      } else {
        message.error(response.message || '菜单创建失败')
        return rejectWithValue(response.message || '菜单创建失败')
      }
    } catch (error: any) {
      message.error(error.message || '菜单创建失败')
      return rejectWithValue(error.message || '菜单创建失败')
    }
  }
)

/**
 * 更新菜单的异步thunk
 * 用于编辑现有菜单项的功能
 */
export const updateMenu = createAsyncThunk(
  'menu/updateMenu',
  async ({ key, data }: { key: string; data: Partial<MenuFormData> }, { rejectWithValue }) => {
    try {
      const response = await menuService.updateMenu(key, data)
      if (response.code === 200) {
        message.success('菜单更新成功')
        return response.data
      } else {
        message.error(response.message || '菜单更新失败')
        return rejectWithValue(response.message || '菜单更新失败')
      }
    } catch (error: any) {
      message.error(error.message || '菜单更新失败')
      return rejectWithValue(error.message || '菜单更新失败')
    }
  }
)

/**
 * 删除菜单的异步thunk
 * 用于删除指定菜单项的功能
 */
export const deleteMenu = createAsyncThunk(
  'menu/deleteMenu',
  async (key: string, { rejectWithValue }) => {
    try {
      const response = await menuService.deleteMenu(key)
      if (response.code === 200) {
        message.success('菜单删除成功')
        return key
      } else {
        message.error(response.message || '菜单删除失败')
        return rejectWithValue(response.message || '菜单删除失败')
      }
    } catch (error: any) {
      message.error(error.message || '菜单删除失败')
      return rejectWithValue(error.message || '菜单删除失败')
    }
  }
)

/**
 * 获取用户权限菜单的异步thunk
 * 根据当前用户权限获取可访问的菜单列表
 */
export const fetchUserMenus = createAsyncThunk(
  'menu/fetchUserMenus',
  async (_, { rejectWithValue }) => {
    try {
      const response = await menuService.getUserMenus()
      if (response.code === 200) {
        return response.data
      } else {
        return rejectWithValue(response.message || '获取用户菜单失败')
      }
    } catch (error: any) {
      return rejectWithValue(error.message || '获取用户菜单失败')
    }
  }
)


/**
 * 获取默认的仪表盘标签页
 */
const getDefaultDashboardTab = (): TabItem => ({
  key: 'dashboard',
  title: '仪表盘',
  path: '/dashboard',
  closable: false,
  affix: true,
  component: 'Dashboard'
})

/**
 * 获取初始标签页列表
 */
const getInitialTabs = (): TabItem[] => [getDefaultDashboardTab()]

/**
 * 菜单模块初始状态
 */
const initialState: MenuState = {
  // 菜单相关初始状态
  menuList: [],
  selectedKeys: [],
  openKeys: [],
  collapsed: false,
  loading: false,
  error: null,
  
  // 面包屑初始状态
  breadcrumbList: [],
  
  // 搜索相关初始状态
  searchValue: '',
  searchVisible: false,
  
  // 标签页相关初始状态 - 结构化格式
  tagList: {
    dataType: 'array',
    content: getInitialTabs(),
    datetime: Date.now()
  },
  tag: {
    dataType: 'string',
    content: 'dashboard',
    datetime: Date.now()
  }
}

/**
 * 确保标签页状态结构完整性的辅助函数
 */
const ensureTagStructure = (state: MenuState) => {
  // 确保 tagList 结构存在
  if (!state.tagList || !state.tagList.content) {
    state.tagList = {
      dataType: 'array',
      content: getInitialTabs(),
      datetime: Date.now()
    }
  }
  
  // 确保 tag 结构存在
  if (!state.tag) {
    state.tag = {
      dataType: 'string',
      content: 'dashboard',
      datetime: Date.now()
    }
  }
}

/**
 * 菜单状态管理的Redux slice
 */
const menuSlice = createSlice({
  name: 'menu',
  initialState,
  reducers: {
    // ============ 菜单相关状态管理 ============
    
    /**
     * 设置菜单列表数据
     */
    setMenuList: (state, action: PayloadAction<MenuItem[]>) => {
      state.menuList = action.payload
    },
    
    /**
     * 设置当前选中的菜单项
     */
    setSelectedKeys: (state, action: PayloadAction<string[]>) => {
      state.selectedKeys = action.payload
    },
    
    /**
     * 设置当前展开的菜单项
     */
    setOpenKeys: (state, action: PayloadAction<string[]>) => {
      state.openKeys = action.payload
    },
    
    /**
     * 切换菜单折叠状态
     */
    toggleCollapsed: (state) => {
      state.collapsed = !state.collapsed
    },
    
    /**
     * 设置菜单折叠状态
     */
    setCollapsed: (state, action: PayloadAction<boolean>) => {
      state.collapsed = action.payload
    },
    
    // ============ 面包屑导航管理 ============
    
    /**
     * 设置面包屑导航列表
     */
    setBreadcrumbList: (state, action: PayloadAction<BreadcrumbItem[]>) => {
      state.breadcrumbList = action.payload
    },
    
    // ============ 搜索功能管理 ============
    
    /**
     * 设置搜索关键词
     */
    setSearchValue: (state, action: PayloadAction<string>) => {
      state.searchValue = action.payload
    },
    
    /**
     * 切换搜索框显示状态
     */
    toggleSearchVisible: (state) => {
      state.searchVisible = !state.searchVisible
    },
    
    /**
     * 设置搜索框显示状态
     */
    setSearchVisible: (state, action: PayloadAction<boolean>) => {
      state.searchVisible = action.payload
    },
    
    // ============ 标签页管理（支持持久化） ============
    
    /**
     * 添加标签页
     * @param state 当前状态
     * @param action 包含新标签页数据的action
     */
    addTab: (state, action: PayloadAction<TabItem>) => {
      const newTab = action.payload
      
      // 确保状态结构完整性
      ensureTagStructure(state)
      
      const existingTab = state.tagList.content.find(tab => tab.key === newTab.key)
      
      // 如果标签页不存在，则添加到列表中
      if (!existingTab) {
        state.tagList.content.push(newTab)
        state.tagList.datetime = Date.now() // 更新时间戳
      }
      
      // 设置为当前激活的标签页
      state.tag.content = newTab.key
      state.tag.datetime = Date.now() // 更新时间戳
    },
    
    /**
     * 移除标签页
     * @param state 当前状态
     * @param action 包含要移除的标签页key的action
     */
    removeTab: (state, action: PayloadAction<string>) => {
      const targetKey = action.payload

      // 确保状态结构完整性
      ensureTagStructure(state)

      // 查找目标标签页
      const tab = state.tagList.content.find(tab => tab.key === targetKey)
      if (!tab || tab.affix) {
        return
      }

      const tabIndex = state.tagList.content.findIndex(tab => tab.key === targetKey)

      if (tabIndex > -1) {
        // 从列表中移除标签页
        state.tagList.content.splice(tabIndex, 1)
        state.tagList.datetime = Date.now()

        // 如果删除后列表为空，添加默认的仪表盘标签页
        if (state.tagList.content.length === 0) {
          state.tagList.content = [getDefaultDashboardTab()]
          state.tag.content = 'dashboard'
          state.tag.datetime = Date.now()
          return
        }

        // 如果删除的是当前激活的标签页，需要切换到其他标签页
        if (state.tag.content === targetKey) {
          // 优先切换到仪表盘
          const dashboardTab = state.tagList.content.find(tab => tab.key === 'dashboard')
          if (dashboardTab) {
            state.tag.content = 'dashboard'
          } else {
            // 如果仪表盘不存在，选择第一个标签页
            state.tag.content = state.tagList.content[0].key
          }
          state.tag.datetime = Date.now()
        }

        // 已移除调试日志输出，避免控制台噪音
      }
    },
    
    /**
     * 设置当前激活的标签页
     * @param state 当前状态
     * @param action 包含标签页key的action
     */
    setActiveTag: (state, action: PayloadAction<string>) => {
      // 确保状态结构完整性
      ensureTagStructure(state)
      state.tag.content = action.payload; state.tag.datetime = Date.now()
    },
    
    /**
     * 切换标签页固定状态
     * @param state 当前状态
     * @param action 包含标签页key的action
     */
    toggleTabPin: (state, action: PayloadAction<string>) => {
      // 确保状态结构完整性
      ensureTagStructure(state)
      const tab = state.tagList.content.find(tab => tab.key === action.payload)
      if (tab) {
        tab.affix = !tab.affix
      }
    },
    
    /**
     * 重新排序标签页（拖拽排序）
     * @param state 当前状态
     * @param action 包含拖拽源索引和目标索引的action
     */
    reorderTabs: (state, action: PayloadAction<{ dragIndex: number; hoverIndex: number }>) => {
      // 确保状态结构完整性
      ensureTagStructure(state)
      const { dragIndex, hoverIndex } = action.payload
      const dragTab = state.tagList.content[dragIndex]
      
      // 移除拖拽的标签页
      state.tagList.content.splice(dragIndex, 1)
      // 在新位置插入
      state.tagList.content.splice(hoverIndex, 0, dragTab)
      // 更新时间戳
      state.tagList.datetime = Date.now()
    },
    
    /**
     * 关闭所有标签页（除了固定标签页）
     * @param state 当前状态
     */
    closeAllTabs: (state) => {
      // 确保状态结构完整性
      ensureTagStructure(state)

      // 保留所有固定标签页和仪表盘
      const fixedTabs = state.tagList.content.filter(tab =>
        tab.affix || tab.key === 'dashboard'
      )

      if (fixedTabs.length > 0) {
        state.tagList.content = fixedTabs
        state.tag.content = fixedTabs[0].key
      } else {
        // 如果没有固定标签页，创建一个默认的仪表盘标签页
        state.tagList.content = [getDefaultDashboardTab()]
        state.tag.content = 'dashboard'
      }

      state.tagList.datetime = Date.now()
      state.tag.datetime = Date.now()
    },
    
    /**
     * 关闭其他标签页（除了指定标签页和固定标签页）
     * @param state 当前状态
     * @param action 包含要保留的标签页key的action
     */
    closeOtherTabs: (state, action: PayloadAction<string>) => {
      // 确保状态结构完整性
      ensureTagStructure(state)
      const keepTabKey = action.payload

      // 确保要保留的标签页存在
      const keepTab = state.tagList.content.find(tab => tab.key === keepTabKey)
      if (!keepTab) {
        return
      }

      // 保留指定的标签页、仪表盘和所有固定标签页
      const filteredTabs = state.tagList.content.filter(tab =>
        tab.key === keepTabKey || tab.affix || tab.key === 'dashboard'
      )

      state.tagList.content = filteredTabs.length > 0 ? filteredTabs : [keepTab]
      state.tag.content = keepTabKey
      state.tagList.datetime = Date.now()
      state.tag.datetime = Date.now()
    },
    
    /**
     * 清除所有404标签页
     * @param state 当前状态
     */
    clearNotFoundTabs: (state) => {
      // 确保状态结构完整性
      ensureTagStructure(state)
      // 过滤掉所有404标签页
      state.tagList.content = state.tagList.content.filter(tab => !tab.key.startsWith('404-')); state.tagList.datetime = Date.now()
      
      // 如果当前激活的标签页是404页面，切换到第一个有效标签页
      if (state.tag.content.startsWith('404-') && state.tagList.content.length > 0) {
        state.tag.content = state.tagList.content[0].key; state.tag.datetime = Date.now()
      }
      
      // 确保至少有一个标签页（仪表盘）
      if (state.tagList.content.length === 0) {
        state.tagList.content = [getDefaultDashboardTab()]; state.tagList.datetime = Date.now()
        state.tag.content = 'dashboard'; state.tag.datetime = Date.now()
      }
    },

    /**
     * 清除错误状态
     * @param state 当前状态
     */
    clearError: (state) => {
      state.error = null
    },
  },
  extraReducers: (builder) => {
    // 获取菜单列表
    builder
      .addCase(fetchMenuList.pending, (state) => {
        state.loading = true
        state.error = null
      })
      .addCase(fetchMenuList.fulfilled, (state, action) => {
        state.loading = false
        state.menuList = action.payload
        state.error = null
      })
      .addCase(fetchMenuList.rejected, (state, action) => {
        state.loading = false
        state.error = action.payload as string
        // 获取失败时保持空数组，由用户重新请求
        state.menuList = []
      })
    
    // 获取用户权限菜单
    builder
      .addCase(fetchUserMenus.pending, (state) => {
        state.loading = true
        state.error = null
      })
      .addCase(fetchUserMenus.fulfilled, (state, action) => {
        state.loading = false
        state.menuList = action.payload
        state.error = null
      })
      .addCase(fetchUserMenus.rejected, (state, action) => {
        state.loading = false
        state.error = action.payload as string
        // 获取失败时保持空数组，由用户重新请求
        state.menuList = []
      })
    
    // 创建菜单
    builder
      .addCase(createMenu.pending, (state) => {
        state.loading = true
        state.error = null
      })
      .addCase(createMenu.fulfilled, (state, action) => {
        state.loading = false
        state.menuList.push(action.payload)
        state.error = null
      })
      .addCase(createMenu.rejected, (state, action) => {
        state.loading = false
        state.error = action.payload as string
      })
    
    // 更新菜单
    builder
      .addCase(updateMenu.pending, (state) => {
        state.loading = true
        state.error = null
      })
      .addCase(updateMenu.fulfilled, (state, action) => {
        state.loading = false
        const index = state.menuList.findIndex(menu => menu.key === action.payload.key)
        if (index !== -1) {
          state.menuList[index] = action.payload
        }
        state.error = null
      })
      .addCase(updateMenu.rejected, (state, action) => {
        state.loading = false
        state.error = action.payload as string
      })
    
    // 删除菜单
    builder
      .addCase(deleteMenu.pending, (state) => {
        state.loading = true
        state.error = null
      })
      .addCase(deleteMenu.fulfilled, (state, action) => {
        state.loading = false
        state.menuList = state.menuList.filter(menu => menu.key !== action.payload)
        state.error = null
      })
      .addCase(deleteMenu.rejected, (state, action) => {
        state.loading = false
        state.error = action.payload as string
      })
  },
})

// ============ 导出actions ============

/**
 * 导出所有同步action creators
 * 用于组件中dispatch调用
 */
export const {
  // 菜单相关actions
  setMenuList,
  setSelectedKeys,
  setOpenKeys,
  toggleCollapsed,
  setCollapsed,
  
  // 面包屑相关actions
  setBreadcrumbList,
  
  // 搜索相关actions
  setSearchValue,
  toggleSearchVisible,
  setSearchVisible,
  
  // 标签页相关actions
  addTab,
  removeTab,
  setActiveTag,
  toggleTabPin,
  reorderTabs,
  closeAllTabs,
  closeOtherTabs,
  clearNotFoundTabs,
  
  // 错误处理actions
  clearError,
} = menuSlice.actions

/**
 * 导出menuSlice的reducer
 * 用于store配置
 */
export default menuSlice.reducer

// ============ 导出selectors ============

/**
 * 状态选择器函数
 * 用于从Redux state中获取特定的菜单状态
 */

/** 获取完整的菜单状态 */
export const selectMenuState = (state: { menu: MenuState }) => state.menu

/** 获取菜单列表数据 */
export const selectMenuList = (state: { menu: MenuState }) => state.menu?.menuList || []

/** 获取菜单加载状态 */
export const selectMenuLoading = (state: { menu: MenuState }) => state.menu?.loading || false

/** 获取菜单错误信息 */
export const selectMenuError = (state: { menu: MenuState }) => state.menu?.error || null

/** 获取选中的菜单项keys */
export const selectSelectedKeys = (state: { menu: MenuState }) => state.menu?.selectedKeys || []

/** 获取展开的菜单项keys */
export const selectOpenKeys = (state: { menu: MenuState }) => state.menu?.openKeys || []

/** 获取菜单折叠状态 */
export const selectCollapsed = (state: { menu: MenuState }) => state.menu?.collapsed || false

/** 获取面包屑导航列表 */
export const selectBreadcrumbList = (state: { menu: MenuState }) => state.menu?.breadcrumbList || []

/** 获取搜索关键词 */
export const selectSearchValue = (state: { menu: MenuState }) => state.menu?.searchValue || ''

/** 获取搜索框显示状态 */
export const selectSearchVisible = (state: { menu: MenuState }) => state.menu?.searchVisible || false

/** 获取标签页列表 */
export const selectTagList = (state: { menu: MenuState }) => state.menu?.tagList?.content || []

/** 获取当前激活的标签页key */
export const selectActiveTag = (state: { menu: MenuState }) => state.menu?.tag?.content || 'dashboard'

/** 获取标签页数据结构（包含元数据） */
export const selectTagListWithMeta = (state: { menu: MenuState }) => state.menu?.tagList

/** 获取当前激活标签页数据结构（包含元数据） */
export const selectActiveTagWithMeta = (state: { menu: MenuState }) => state.menu?.tag